package com.java1234.controller;

import com.java1234.entity.*;
import com.java1234.service.LeaveService;
import com.java1234.util.ResponseUtil;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.activiti.engine.*;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * Created by dengwubo on 2017/8/25.
 */
@SuppressWarnings("all")
@Controller
@RequestMapping("/task")
public class TaskController {

    @Resource
    private TaskService taskService;
    @Resource
    private RepositoryService repositoryService;

    @Resource
    private FormService formService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private LeaveService leaveService;
    @Resource
    private HistoryService historyService;



    @RequestMapping("/list")
    public String list(@RequestParam(value="page",required=false)String page, @RequestParam(value="rows",required=false)String rows,
                       @RequestParam(value = "s_name",required = false,defaultValue = "") String s_name, String userId, HttpServletResponse response) throws Exception {
        PageBean pageBean = new PageBean(Integer.parseInt(page),Integer.parseInt(rows));
        List<Task> tasks = taskService.createTaskQuery()   //创建任务查询
                .taskCandidateUser(userId)  //根据用户id查询
                .taskNameLike("%" + s_name + "%")   //根据任务名称查询
                .listPage(pageBean.getStart(), pageBean.getPageSize());//返回带分页的结果集合
        List<MyTask> taskList = new ArrayList<>();
        tasks.forEach(task->{
            MyTask myTask = new MyTask();
            myTask.setId(task.getId());
            myTask.setName(task.getName());
            myTask.setCreateTime(task.getCreateTime());
            taskList.add(myTask);
        });
        long total = taskService.createTaskQuery().taskCandidateUser(userId).taskNameLike("%"+s_name+"%").count(); //获取总记录数
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
        JSONObject result = new JSONObject();
        JSONArray jsonArray = JSONArray.fromObject(taskList,jsonConfig);
        result.put("rows",jsonArray);
        result.put("total",total);
        ResponseUtil.write(response,result);


        return null;
    }

    /**
     * 获取当前任务的执行流程
     * 1. 根据任务id 获取当前任务对象
     * 2. 获取任务对象的属性 流程定义Id
     * 3. 根据流程定义ID获取流程定义对象
     * 4. 根据流程定义对象 可以获取 deploymentId 和 diagramResourceName
     * 5. 根据deploymentId 和 diagramResourceName 可以获取流程部署总图
     * 6. 根据流程定义Id 获取流程定义实体
     * 7. 通过任务对象获取当前任务的流程实例
     * 8. 通过processDefinitionEntity 的 findActivity 方法 ActivityId 作为参数 获取活动对象
     * 9. 通过活动对象 活动当前在视图中的位置
     * @param taskId
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/showCurrentView")
    public ModelAndView showCurrentView(String taskId,HttpServletResponse response) throws  Exception{
        ModelAndView mav = new ModelAndView();
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();
        String processDefinitionId  = task.getProcessDefinitionId(); // 获取流程定义Id
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() // 查询流程定义对象
                .processDefinitionId(processDefinitionId)
                .singleResult();
        mav.addObject("deploymentId",processDefinition.getDeploymentId()); //部署id
        mav.addObject("diagramResourceName",processDefinition.getDiagramResourceName());// 图片资源文件名称
        // 获取流程定义实体类
        ProcessDefinitionEntity	processDefinitionEntity=(ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);

        String processInstanceId = task.getProcessInstanceId();//获取流程实例ID
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

        ActivityImpl activity = processDefinitionEntity.findActivity(pi.getActivityId());
        mav.addObject("x",activity.getX());
        mav.addObject("y",activity.getY());
        mav.addObject("width",activity.getWidth());
        mav.addObject("height",activity.getHeight());
        mav.setViewName("page/currentView");

    return mav;
    }

    @RequestMapping("/redirectPage")
    public String redirectPage(String taskId,HttpServletResponse response)throws Exception{
        TaskFormData formData = formService.getTaskFormData(taskId);
        String url = formData.getFormKey();
        JSONObject result = new JSONObject();
        result.put("url",url);
        ResponseUtil.write(response,result);
        return null;
    }



    @RequestMapping("/audit_bz")
    public String audit_bz(String taskId, Integer leaveDays,String comment, Integer state, HttpServletResponse response, HttpSession session)throws  Exception{

        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();
        Map<String,Object> variables = new HashMap<>();
        if (state==1){
            variables.put("msg","通过");
        }else{
            Integer leaveId  = (Integer)taskService.getVariable(taskId,"leaveId");
            Leave leave =leaveService.findById(leaveId);
            leave.setState("审核未通过");
            leaveService.update(leave);
            variables.put("msg","未通过");
        }
        variables.put("days",leaveDays);
        String processInstancedId = task.getProcessInstanceId(); //获取流程实例Id
        MemberShip currentMemberShip = (MemberShip)session.getAttribute("currentMemberShip"); //获取当前登录用户的信息
        User currentUser = currentMemberShip.getUser();
        Group currentGroup = currentMemberShip.getGroup();
        Authentication.setAuthenticatedUserId(currentUser.getFirstName()+currentUser.getLastName()+"["+currentGroup.getName()+"]"); // 设置用户ID,让程序知道是哪个组的哪个人操作的
        taskService.addComment(taskId,processInstancedId,comment);// 添加批注信息
        taskService.complete(taskId,variables); // 完成任务
        JSONObject result = new JSONObject();
        result.put("success",true);
        ResponseUtil.write(response,result);
        return null;
    }

    @RequestMapping("/toListHistory")
    public ModelAndView toListHistory(String processInstanceId){
        ModelAndView mav = new ModelAndView();
        mav.addObject("processInstanceId",processInstanceId);
        mav.setViewName("page/historyCommentList");
        return mav;
    }

    @RequestMapping("/listHistoryComment")
    public String listHistoryComment(String taskId,HttpServletResponse response,String processInstanceId)throws Exception{
        if (taskId==null){
            List<Comment> commentList = taskService.getProcessInstanceComments(processInstanceId);
            Collections.reverse(commentList);
            JsonConfig jsonConfig = new JsonConfig();
            jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
            JSONObject result = new JSONObject();
            JSONArray jsonArray = JSONArray.fromObject(commentList,jsonConfig);
            result.put("rows",jsonArray);
            ResponseUtil.write(response,result);

        }else{

            HistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();//获取历史任务实例
            //通过历史任务的流程实例ID获取所有的历史任务批注
            List<Comment> commentList = taskService.getProcessInstanceComments(hti.getProcessInstanceId());
            Collections.reverse(commentList);
            JsonConfig jsonConfig = new JsonConfig();
            jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
            JSONObject result = new JSONObject();
            JSONArray jsonArray = JSONArray.fromObject(commentList,jsonConfig);
            result.put("rows",jsonArray);            ResponseUtil.write(response,result);

        }
        return null;

    }

    @RequestMapping("/audit_ld")
    public String aduit_ld(String taskId,String comment,Integer state,HttpServletResponse response,HttpSession session)throws Exception{

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Integer leaveId = (Integer)taskService.getVariable(taskId,"leaveId");
        Leave leave = leaveService.findById(leaveId);
        if (state==1){
            leave.setState("审核通过");
            leaveService.update(leave);
        }else{
            leave.setState("审核未通过");
            leaveService.update(leave);
        }
        String processInstenceId = task.getProcessInstanceId(); // 获取流程实例ID
        MemberShip currentMemberShip = (MemberShip) session.getAttribute("currentMemberShip");
        User currentUser = currentMemberShip.getUser();
        Group currentGroup = currentMemberShip.getGroup();
        Authentication.setAuthenticatedUserId(currentUser.getFirstName()+currentUser.getLastName()+"["+currentGroup.getName()+"]"); // 设置用户id
        taskService.addComment(taskId,processInstenceId,comment);
        taskService.complete(taskId);
        JSONObject result = new JSONObject();
        result.put("success",true);
        ResponseUtil.write(response,result);
        return null;
    }

    @RequestMapping("/unFinishedList")
    public String unFinishedList(@RequestParam(value="page",required=false)String page,@RequestParam(value="rows",required=false)String rows,
                                 @RequestParam(value = "s_name",required = false,defaultValue = "")String s_name,String groupId,String userId,HttpServletResponse response)throws Exception{


        PageBean pageBean = new PageBean(Integer.parseInt(page),Integer.parseInt(rows));
        // 根据角色查询历史任务
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery() //创建历史任务实例查询
                .taskCandidateGroup(groupId)    //根据角色查询
                .taskNameLike("%" + s_name + "%")   // 根据任务名称查询
                .list();
        List<MyTask> taskList = new ArrayList<>();


        htiList.forEach(hti->{
            if ((taskService.createTaskQuery().processInstanceId(hti.getProcessInstanceId()).singleResult()!=null)&& //根据任务历史的流程实例ID ,查询尚未完成的任务实例
                    taskService.createTaskQuery().taskCandidateUser(userId).taskId(hti.getId()).list().size()==0){ // 查询尚未完成任务已经完成的活动实例
                MyTask myTask = new MyTask();
                myTask.setId(hti.getId());
                myTask.setName(hti.getName());
                myTask.setCreateTime(hti.getCreateTime());
                myTask.setEndTime(hti.getEndTime());
                taskList.add(myTask);
            }

        });
        if (taskList.size()>(pageBean.getStart()+pageBean.getPageSize())){ // 如果历史任务数量大于当前页所容纳的数量时,只截取当前页长度的数据
            taskList.subList(pageBean.getStart(),pageBean.getStart()+pageBean.getPageSize());
        }
       // System.out.println("==========="+taskList.size()+"==========");
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
        JSONObject result = new JSONObject();
        JSONArray jsonArray = JSONArray.fromObject(taskList,jsonConfig);
        result.put("rows",jsonArray);
        result.put("total",taskList.size());
        ResponseUtil.write(response,result);
        return null;
    }

    /**
     * 根据任务id查询流程实例的具体执行过程
     * @param taskId
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/listAction")
    public String listAction(String taskId,HttpServletResponse response) throws Exception{
        HistoricTaskInstance hti =historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); // 查询此任务的历史任务
        String processInstanceId = hti.getProcessInstanceId(); // 获取流程实例id
        //历史活动实例查询,根据历史任务的流程实例ID进行查询
        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
        JSONObject result = new JSONObject();
        JSONArray jsonArray = JSONArray.fromObject(haiList,jsonConfig);
        result.put("rows",jsonArray);
        ResponseUtil.write(response,result);

        return null;
    }

    /**
     * 查看当前流程图,待办用到的
     * @param taskId
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/showHisCurrentView")
    public ModelAndView showHisCurrentView(String taskId,HttpServletResponse response)throws Exception{
        ModelAndView mav = new ModelAndView();
        // 根据历史任务ID 查询历史任务
        HistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        String processDefinitionId = hti.getProcessDefinitionId(); // 获取流程定义ID
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() // 创建流程定义查询
                .processDefinitionId(processDefinitionId) // 根据流程定义ID查询
                .singleResult();
        mav.addObject("deploymentId",processDefinition.getDeploymentId()); // 设置流程部署ID
        mav.addObject("diagramResourceName",processDefinition.getDiagramResourceName());// 图片资源文件名称

        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
        String processInstanceId = hti.getProcessInstanceId(); //获取历史任务的流程实例ID
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() // 根据流程实例ID获取流程实例对象
                .processInstanceId(processInstanceId)
                .singleResult();
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(processInstance.getActivityId());
        mav.addObject("x",activityImpl.getX());
        mav.addObject("y",activityImpl.getY());
        mav.addObject("width",activityImpl.getWidth());
        mav.addObject("height",activityImpl.getHeight());
        mav.setViewName("page/currentView");

        return mav;
    }

    /**
     * 流程实例走完的历史任务
     * @param page
     * @param rows
     * @param s_name
     * @param groupId
     * @param response
     * @return
     * @throws Exception
     */
     @RequestMapping("/finishedList")
     public String finishedList(@RequestParam(value="page",required=false)String page,@RequestParam(value="rows",required=false)String rows,
                                @RequestParam(value = "s_name",defaultValue = "",required = false) String s_name,String groupId,HttpServletResponse response)
     throws Exception{
        PageBean pageBean = new PageBean(Integer.parseInt(page),Integer.parseInt(rows));
        // 查询这个角色下的历史任务
         List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery() //创建历史任务实力查询
                 .taskCandidateGroup(groupId)
                 .taskNameLike("%" + s_name + "%")
                 .list();
         List<MyTask> taskList = new ArrayList<>();
         List<MyTask> finalTaskList = taskList;
         htiList.forEach(hti->{
             if (taskService.createTaskQuery().processInstanceId(hti.getProcessInstanceId()).singleResult()==null){
                MyTask myTask = new MyTask();
                myTask.setId(hti.getId());
                myTask.setName(hti.getName());
                myTask.setCreateTime(hti.getCreateTime());
                myTask.setEndTime(hti.getEndTime());

                 finalTaskList.add(myTask);
             }

         });
         if (taskList.size()>(pageBean.getStart()+pageBean.getPageSize())){
             taskList = finalTaskList.subList(pageBean.getStart(),pageBean.getStart()+pageBean.getPageSize());

         }
         JsonConfig jsonConfig = new JsonConfig();
         jsonConfig.registerJsonValueProcessor(Date.class,new DateJsonValueProcessor("yyyy-MM-dd hh:mm:ss"));
         JSONObject result = new JSONObject();
         JSONArray jsonArray = JSONArray.fromObject(taskList,jsonConfig);
         result.put("rows",jsonArray);
         result.put("total", taskList.size());
         ResponseUtil.write(response, result);
         return null;
     }


}

